package com.yuezhu.com_volley;

import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager.NameNotFoundException;
import android.os.Build;

import com.android.volley.Network;
import com.android.volley.RequestQueue;
import com.android.volley.toolbox.BasicNetwork;
import com.android.volley.toolbox.DiskBasedCache;
import com.android.volley.toolbox.HttpClientStack;
import com.android.volley.toolbox.HttpStack;
import com.yuezhu.global.ApplicationContext;

import org.apache.http.HttpHost;
import org.apache.http.HttpVersion;
import org.apache.http.client.HttpClient;
import org.apache.http.conn.ClientConnectionManager;
import org.apache.http.conn.params.ConnManagerParams;
import org.apache.http.conn.params.ConnRouteParams;
import org.apache.http.conn.scheme.PlainSocketFactory;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.scheme.SchemeRegistry;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;
import org.apache.http.params.HttpProtocolParams;
import org.apache.http.protocol.HTTP;

import java.io.File;

/**
 * Volley的封装，使用OkRequestQueue
 */
public class OkVolley {
    private static HttpClient httpClient;
    private static HttpParams params = null;

    private static OkRequestQueue mDefaultRequestQueue;

    private OkVolley() {}

    /**
     * Default on-disk cache directory.
     */
    private static final String DEFAULT_CACHE_DIR = "volley";

    /**
     * Creates a default instance of the worker pool and calls {@link RequestQueue#start()} on it.
     * You may set a maximum size of the disk cache in bytes.
     *
     * @param context           A {@link Context} to use for creating the cache dir.
     * @param stack             An {@link HttpStack} to use for the network, or null for default.
     * @param maxDiskCacheBytes the maximum size of the disk cache, in bytes. Use -1 for default size.
     * @return A started {@link RequestQueue} instance.
     */
    public static OkRequestQueue newOkRequestQueue(Context context, HttpStack stack, int maxDiskCacheBytes) {
        File cacheDir = new File(context.getCacheDir(), DEFAULT_CACHE_DIR);

        String userAgent = "volley/0";
        try {
            String packageName = context.getPackageName();
            PackageInfo info = context.getPackageManager().getPackageInfo(packageName, 0);
            userAgent = packageName + "/" + info.versionCode;
        } catch (NameNotFoundException e) {
        }

        if (stack == null) {
            if (Build.VERSION.SDK_INT >= 9) {
//                stack = new HurlStack();
                stack = new OkHurlStack();
            } else {
                // Prior to Gingerbread, HttpUrlConnection was unreliable.
                // See: http://android-developers.blogspot.com/2011/09/androids-http-clients.html
//                stack = new HttpClientStack(AndroidHttpClient.newInstance(userAgent));
                stack = new HttpClientStack(getHttpClient());
            }
        }

        Network network = new BasicNetwork(stack);

        OkRequestQueue queue;
        if (maxDiskCacheBytes <= -1) {
            // No maximum size specified
            queue = new OkRequestQueue(new DiskBasedCache(cacheDir), network);
        } else {
            // Disk cache size specified
            queue = new OkRequestQueue(new DiskBasedCache(cacheDir, maxDiskCacheBytes), network);
        }

        queue.start();

        return queue;
    }

    private static synchronized HttpClient getHttpClient() {
        httpClient();
        Context _con = ApplicationContext.getContext();
        ConnectManager conn = new ConnectManager(_con);

        if (conn.isWapNetwork()) {
            if (params.getParameter(ConnRouteParams.DEFAULT_PROXY) != null) {
                params.removeParameter(ConnRouteParams.DEFAULT_PROXY);
            }

            String _host = conn.getProxy();
            int _port = Integer.valueOf(conn.getProxyPort());

            httpClient.getParams().setBooleanParameter(
                    "http.protocol.expect-continue", false);

            HttpHost httpHost = new HttpHost(_host, _port);
            params.setParameter(ConnRouteParams.DEFAULT_PROXY, httpHost);
        } else {
            if (params.getParameter(ConnRouteParams.DEFAULT_PROXY) != null) {
                params.removeParameter(ConnRouteParams.DEFAULT_PROXY);
            }
        }

        return httpClient;
    }

    /**
     * 生成httpclient对象支持http协议
     */
    private static synchronized void httpClient() {
        if (null == httpClient) {
            params = new BasicHttpParams();
            HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
            HttpProtocolParams.setContentCharset(params,
                    HTTP.DEFAULT_CONTENT_CHARSET);
            HttpProtocolParams.setUseExpectContinue(params, true);

            ConnManagerParams.setTimeout(params, 10 * 1000);
            HttpConnectionParams.setConnectionTimeout(params, 10 * 1000);
            HttpConnectionParams.setSoTimeout(params, 60 * 1000);

            SchemeRegistry schReg = new SchemeRegistry();
            schReg.register(new Scheme("http", PlainSocketFactory
                    .getSocketFactory(), 80));

            ClientConnectionManager connManager = new ThreadSafeClientConnManager(
                    params, schReg);

            httpClient = new DefaultHttpClient(connManager, params);

        }
    }

    /**
     * Creates a default instance of the worker pool and calls {@link RequestQueue#start()} on it.
     * You may set a maximum size of the disk cache in bytes.
     *
     * @param context           A {@link Context} to use for creating the cache dir.
     * @param maxDiskCacheBytes the maximum size of the disk cache, in bytes. Use -1 for default size.
     * @return A started {@link RequestQueue} instance.
     */
    public static OkRequestQueue newOkRequestQueue(Context context, int maxDiskCacheBytes) {
        return newOkRequestQueue(context, null, maxDiskCacheBytes);
    }

    /**
     * Creates a default instance of the worker pool and calls {@link RequestQueue#start()} on it.
     *
     * @param context A {@link Context} to use for creating the cache dir.
     * @param stack   An {@link HttpStack} to use for the network, or null for default.
     * @return A started {@link RequestQueue} instance.
     */
    public static OkRequestQueue newOkRequestQueue(Context context, HttpStack stack) {
        return newOkRequestQueue(context, stack, -1);
    }

    /**
     * Creates a default instance of the worker pool and calls {@link RequestQueue#start()} on it.
     *
     * @param context A {@link Context} to use for creating the cache dir.
     * @return A started {@link RequestQueue} instance.
     */
    public static OkRequestQueue newOkRequestQueue(Context context) {
        return newOkRequestQueue(context, null);
    }

    /**
     * 生成一个默认的RequestQueue
     * @param context
     * @return
     */
    public synchronized static OkRequestQueue getDefaultRequestQueue(Context context) {
        if(mDefaultRequestQueue == null) {
            mDefaultRequestQueue = newOkRequestQueue(context);
        }

        return mDefaultRequestQueue;
    }
}